/**
 * Copyright (c) 2012, Hakans Pirates - 
 * Johan Andersson spaiki17@gmail.com, 
 * Mattias Lundberg lundberg.mattias@gmail.com, 
 * Samuel Sjodin sjoodin@gmail.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the <organization> nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *  
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package pirates;

import com.jme3.app.SimpleApplication;
import com.jme3.asset.plugins.FileLocator;
import com.jme3.bullet.BulletAppState;
import com.jme3.font.BitmapFont;
import com.jme3.network.Client;
import com.jme3.network.Network;
import com.jme3.scene.Node;
import com.jme3.scene.control.CameraControl;
import java.io.IOException;
import java.net.ConnectException;
import pirates.chat.ChatDisplay;
import pirates.inputDevices.KeyMouseControl;
import pirates.network.ClientNetListener;
import pirates.network.ClientNetSender;
import pirates.notifications.Notify;
import pirates.ship.ShipControl;
import pirates.ship.ShipState;
import pirates.terrain.TerrainState;
import pirates.terrain.water.PostWaterState;
import pirates.terrain.water.SimpleWaterState;

/**
 * 
 * @author Mattias
 */
public class Pirates extends SimpleApplication {

	ClientNetListener netListener;
	ClientNetSender netSender;
	private Thread clientNetSenderThread;
	private ChatDisplay chat;
	public ShipState ships;
	public Client myClient = null;
	public BulletAppState bulletAppState;
	private Node crateNode;

	@Override
	public void stop() {
		netSender.close();
		super.stop();
	}

	public BitmapFont getFont() {
		return guiFont;
	}

	@Override
	public void simpleInitApp() {
		guiNode.detachAllChildren(); // remove debug text
		bulletAppState = new BulletAppState();
		stateManager.attach(bulletAppState);

		assetManager.registerLocator("assets/", FileLocator.class); // needed so
																	// that
																	// running
																	// in
																	// Eclipse
																	// works

		TerrainState terrain = new TerrainState(this);
		stateManager.attach(terrain);

		ships = new ShipState(this, myClient);

		if (Settings.FANCY_WATER) {
			PostWaterState water = new PostWaterState(this);
			stateManager.attach(water);
		} else {
			SimpleWaterState simpleWater = new SimpleWaterState(this);
			stateManager.attach(simpleWater);
		}
		// ships.createShip(Settings.BATTLESHIP_MODEL,
		// new Vector3f(-600f, 0f, 0f),
		// Settings.HOST_NAME,
		// Settings.EntityModels.BATTLESHIP.getValues(),
		// Settings.EntityTeam.BRITISH.getValues());

		stateManager.attach(ships);

		crateNode = new Node("Crates");
		rootNode.attachChild(crateNode);

		try {
			myClient = Network.connectToServer(Settings.SERVER_IP_ADDRESS,
					Settings.NW_PORT);

			netListener = new ClientNetListener(myClient, this); // starting the
																	// net
																	// listener
			myClient.start(); // starting the TCP/UDP communication (connecting
								// to server)
			netSender = new ClientNetSender(myClient, this); // starting the net
																// sender
			clientNetSenderThread = new Thread(netSender);
                        clientNetSenderThread.setPriority(Thread.MAX_PRIORITY);
			clientNetSenderThread.start();

			chat = new ChatDisplay(guiNode, assetManager, myClient);
			chat.attach();
		} catch (ConnectException e) {
			Notify.popup("Failed to connect to server");
			System.exit(0);
		} catch (IOException e) {
			Notify.popup("IO Exception");
			System.exit(0);
		}

	}

	public ChatDisplay getChat() {
		return chat;
	}
	float sumTime = 0;

	@Override
	public void simpleUpdate(float tpf) {
		chat.displayMessage(settings.getHeight() / 2);
		sumTime += tpf;
		if (sumTime > 60 || tpf > 1) {
			sumTime = 0;
			System.gc();
		}
	}

	public Node getCrateNode() {
		return crateNode;
	}

	public void controlShip() {
		Node player = ships.getShip(Settings.HOST_NAME);
		if (player == null) {
			Notify.debug("playerIsNull!");
		}
		player.addControl(new KeyMouseControl(this, inputManager, chat));
		player.getControl(ShipControl.class).setDebug(true);

		CameraControl cameraControl = new CameraControl(cam,
				CameraControl.ControlDirection.SpatialToCamera);
		player.getChild(Settings.CAMERA_NODE).addControl(cameraControl);
	}
}
